
package com.atom.module.image.filter;


public class BrightContrastFilter implements IImageFilter {

	 /// <summary>
    /// The brightness factor.
    /// Should be in the range [-1, 1].
    /// </summary>
    public float brightnessFactor = 0.25f;

    /// <summary>
    /// The contrast factor.
    /// Should be in the range [-1, 1].
    /// </summary>
    public float contrastFactor = 0f;
    
    //@Override
    public Image process(Image imageIn) {
    	 int r,g,b;
         // Convert to integer factors
         int bfi = (int)(brightnessFactor * 255);
         float cf = 1f + contrastFactor;
         cf *= cf;
         int cfi = (int)(cf * 32768) + 1;
         for (int x = 0; x < imageIn.getWidth(); x++) {
             for (int y = 0; y < imageIn.getHeight(); y++) {
                 r = imageIn.getRComponent(x, y);
                 g = imageIn.getGComponent(x, y);
                 b = imageIn.getBComponent(x, y);  
                 // Modify brightness (addition)
                 if (bfi != 0)
                 {
                    // Add brightness
                 	int ri = r + bfi;
                 	int gi = g + bfi;
                 	int bi = b + bfi;
                    // Clamp to byte boundaries
                    r = ri > 255 ? 255 : (Math.max(ri, 0));
                    g = gi > 255 ? 255 : (Math.max(gi, 0));
                    b = bi > 255 ? 255 : (Math.max(bi, 0));
                 }
                 // Modifiy contrast (multiplication)
                 if (cfi != 32769){
                    // Transform to range [-128, 127]
                    int ri = r - 128;
                    int gi = g - 128;
                    int bi = b - 128;

                    // Multiply contrast factor
                    ri = (ri * cfi) >> 15;
                    gi = (gi * cfi) >> 15;
                    bi = (bi * cfi) >> 15;

                    // Transform back to range [0, 255]
                    ri = ri + 128;
                    gi = gi + 128;
                    bi = bi + 128;

                    // Clamp to byte boundaries
                    r = ri > 255 ? 255 : (Math.max(ri, 0));
                    g = gi > 255 ? 255 : (Math.max(gi, 0));
                    b = bi > 255 ? 255 : (Math.max(bi, 0));
                 }  
                 imageIn.setPixelColor(x, y, r, g, b);
             }
         }
         return imageIn;
    }

    @Override
    public String toString() {
        return "BrightContrastFilter{" +
            "brightnessFactor=" + brightnessFactor +
            ", contrastFactor=" + contrastFactor +
            '}';
    }
}
